
package com.be.beadmin.device.impl;

import com.alibaba.excel.util.StringUtils;
import com.be.beadmin.common.entity.PageEntity;
import com.be.beadmin.device.entity.DeFile;
import com.be.beadmin.device.entity.DeFile_;
import cn.hutool.core.util.ObjectUtil;

import com.be.beadmin.common.exception.BeadminException;
import com.be.beadmin.common.utils.JpaQueryBuilder;
import com.be.beadmin.common.utils.JpaSortBuilder;
import com.be.beadmin.device.entity.DeInfo;
import com.be.beadmin.device.entity.EhsFile;
import com.be.beadmin.device.entity.EhsItem;
import com.be.beadmin.device.repository.DeInfoRepository;
import com.be.beadmin.project.Util.MinioUtil;
import com.be.beadmin.project.config.MinioConfig;
import com.be.beadmin.service.impl.MinioService;
import com.be.beadmin.service.service.SerialNumberService;
import io.minio.MinioClient;
import lombok.RequiredArgsConstructor;
import com.be.beadmin.device.mapper.DeFileMapperEx;
import com.be.beadmin.device.repository.DeFileRepository;
import com.be.beadmin.device.service.DeFileService;
import com.be.beadmin.device.dto.input.DeFileDto;
import com.be.beadmin.device.dto.output.DeFileEx;
import com.be.beadmin.device.dto.input.DeFileQueryCriteria;
import com.be.beadmin.device.mapper.DeFileMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Order;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
* @description 服务实现
* @author chenxu
* @date 2023-11-12
**/
@Service
@RequiredArgsConstructor
public class DeFileServiceImpl implements DeFileService {

    @Autowired
    private DeFileRepository deFileRepository;
    @Autowired
    private DeInfoRepository deInfoRepository;
    @Autowired
    private DeFileMapper deFileMapper;
    @Autowired
    private SerialNumberService serialNumberService;
    @Autowired
    private DeFileMapperEx deFileExMapper;
    @Autowired
    private MinioService minioService;
    MinioUtil minioUtil = new MinioUtil();

    @Override
    public Page<DeFileEx> getDeFileByPage(PageEntity pageEntity) {
        Pageable pageable = PageRequest.of(
                pageEntity.getCurrent() - 1,
                pageEntity.getPageSize());
        Page<DeFile> page = deFileRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
                    List<Predicate> list = new ArrayList<>();
                    Predicate pre1 = JpaQueryBuilder.getPredicate(root, pageEntity.getFilters(), criteriaBuilder);
                    list.add(pre1);
                    Predicate pre2 = criteriaBuilder.equal(root.get(DeFile_.delete), 0); //过滤为0
                    list.add(pre2);
                    Predicate[] p = new Predicate[list.size()];
                    List<Order> orders = new ArrayList<>();
                    if (pageEntity.getSorters() != null && pageEntity.getSorters().size() > 0) {
                        orders = JpaSortBuilder.getPredicate(root, pageEntity.getSorters(), criteriaBuilder);
                        criteriaQuery.orderBy(orders);
                    } else {
                        criteriaQuery.orderBy(criteriaBuilder.desc(root.get(DeFile_.createTime).as(Date.class)));
                    }
                    return criteriaBuilder.and(list.toArray(p));
                }
                , pageable);
        Page<DeFileEx> page1 = page.map(deFileExMapper::toEntity);
        return page1;

    }

    @Override
    public void addDeFile(DeFileDto deFileDto) {
        DeFile result = deFileRepository.findDeFileByIdAndDelete(deFileDto.getId(), 0);
        if (ObjectUtil.isNotEmpty(result)) {
            throw new BeadminException("DeFile不存在,请重新查询");
        }
        DeFile deFile = deFileMapper.toEntity(deFileDto);
        deFileRepository.save(deFile);
    }

    @Override
    public void updateDeFile(DeFileDto deFileDto) {
        DeFile deFile = deFileRepository.findDeFileById(deFileDto.getId());
        deFile = deFileMapper.toEntity(deFileDto);
        deFileRepository.save(deFile);
    }


    @Override
    public String previewDeFile(String id) throws Exception {
        DeFile deFile = deFileRepository.findDeFileById(id);
        return minioUtil.getPreviewFileUrl(deFile.getBucketName(), deFile.getNewFileName());
    }

    @Override
    public void downloadDeFile(String id, HttpServletResponse response) throws Exception {
        DeFile deFile = deFileRepository.findDeFileById(id);
        MinioClient minioClient = MinioConfig.getMinioClient();
        InputStream inputStream = null;
        OutputStream outputStream = null;
        if (StringUtils.isBlank(deFile.getNewFileName())) {
            response.setHeader("Content-type", "text/html;charset=UTF-8");
            String data = "文件下载失败";
            OutputStream ps = response.getOutputStream();
            ps.write(data.getBytes("UTF-8"));
            return;
        }

        outputStream = response.getOutputStream();
        // 获取文件对象
        inputStream = minioClient.getObject(deFile.getBucketName(), deFile.getNewFileName());
        byte buf[] = new byte[1024];
        int length = 0;
        response.reset();
        String fileName = URLEncoder.encode(deFile.getNewFileName(), "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName);
        response.setContentType("application/octet-stream");
        // 输出文件
        while ((length = inputStream.read(buf)) > 0) {
            outputStream.write(buf, 0, length);
        }
        System.out.println("下载成功");
        inputStream.close();
        outputStream.close();
        if (inputStream != null) {
            inputStream.close();
        }
    }

    @Override
    public void delDeFile(String id) {
        DeFile deFile = deFileRepository.findDeFileById(id);
        deFile.setDelete(1);
        deFileRepository.save(deFile);
    }

    @Override
    public void delDeFiles(List<String> ids) {
    }

    @Override
    public void uploadDeFile(String deitemId, MultipartFile[] multipartFile, String fileName, String memo, String bucketName) throws Exception {
        DeInfo deItem = deInfoRepository.findDeInfoById(deitemId);
        //对文件进行操作
        for (MultipartFile file : multipartFile) {
            DeFile deFileDto = new DeFile();

            //文件名
//            if (fileName == null || fileName.equals("")) {
//                fileName = multipartFile.getOriginalFilename();
//            }
            fileName = file.getOriginalFilename();
            deFileDto.setFileName(fileName);

            //判断同一个项目是否有相同的文件名
            int f = deFileRepository.countDeFilesByFileNameAndDeviceNameAndDelete(fileName, deItem.getDeviceName(), 0);

            //文件后缀
            String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
            deFileDto.setFileExtEndDate(ext);
            String version;
            while (true) {
                version = "v1." + f;
                int num = deFileRepository.countDeFilesByFileNameAndVersionAndDelete(fileName, version, 0);
                if (num == 0) {
                    break;
                } else {
                    f++;
                }
            }
            //System.out.println("version:"+version);
            deFileDto.setVersion(version);

            //文件大小
            BigDecimal fileSize = new BigDecimal(file.getSize());
            deFileDto.setFileSize(fileSize);
            //流水号
            //fileInfoDto.setSerialNo(serialNo);
            String fileCode = serialNumberService.getNextSnByCode("FileCode");
            deFileDto.setFileCode(fileCode);
            //项目id
            deFileDto.setDeitem_id(deitemId);

            //项目名称
            deFileDto.setDeviceName(deItem.getDeviceName());
            //备注
            deFileDto.setMemo(memo);
            //设置bucketName
            deFileDto.setBucketName(bucketName);
            //System.out.println(fileInfoDto.toString());
            //处理文件

            String newFileName = fileName.substring(0, fileName.lastIndexOf(".")) + "-" + version + "." + ext;
//        //minioUtil.uploadFile(multipartFile,newFileName,bucketName);
//
//        minioService.uploadFile(bucketName,newFileName,multipartFile);
//        MinioClient minioClient = MinioConfig.getMinioClient();
////        String fileUrl = minioService.getObjectUrl(bucketName , newFileName);
//        String fileUrl = minioClient.presignedGetObject(bucketName , newFileName);
            String fileUrl = minioUtil.uploadFile3(file, bucketName, newFileName);
            deFileDto.setFileUrl(fileUrl);
            deFileDto.setNewFileName(newFileName);
            deFileRepository.save(deFileDto);
        }

    }
}